package com.jvm.cpu;

import org.openjdk.jol.info.ClassLayout;

public final class FalseSharing implements Runnable {
    public final static int NUM_THREADS = 4; // change
    public final static long ITERATIONS = 500L * 1000L * 1000L;
    private final int arrayIndex;

    private static VolatileLong[] longs = new VolatileLong[NUM_THREADS];

    static {
        for (int i = 0; i < longs.length; i++) {
            longs[i] = new VolatileLong();
        }
    }

    public FalseSharing(final int arrayIndex) {
        this.arrayIndex = arrayIndex;
    }

    public static void main(final String[] args) throws Exception {
        main();
        final long start = System.currentTimeMillis();
        // runTest();
        System.out.println("duration = " + (System.currentTimeMillis() - start));
    }

    private static void runTest() throws InterruptedException {
        Thread[] threads = new Thread[NUM_THREADS];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new FalseSharing(i));
        }
        for (Thread t : threads) {
            t.start();
        }
        for (Thread t : threads) {
            t.join();
        }
    }

    public void run() {
        long i = ITERATIONS + 1;
        while (0 != --i) {
            longs[arrayIndex].value = i;
        }
    }

    /**
     *  @Contended 必须开启
     *
     * -XX:-RestrictContended
     *
     * -XX:ContendedPaddingWidth=64 指定对其大小
     */
    public final static class VolatileLong {
        // @Contended
        public  volatile long value = 0L;
        // public volatile  long value02 = 0L;
        // public long p1, p2, p3, p4, p5, p6,p7; // 填充，可以注释后对比测试
    }

    static void print(String message) {
        System.out.println(message);
        System.out.println("-------------------------");
    }

    public static void main() throws InterruptedException {
        print(ClassLayout.parseInstance(new VolatileLong()).toPrintable());
    }


}